home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / system / emulator / uae-0.000 / uae-0 / uae-0.6.0 / hardfile.c < prev    next >
C/C++ Source or Header  |  1996-05-04  |  9KB  |  386 lines

  1.  /*
  2.   * UAE - The Un*x Amiga Emulator
  3.   *
  4.   * AutoConfig devices
  5.   *
  6.   * (c) 1995 Bernd Schmidt
  7.   */
  8.  
  9. #include "sysconfig.h"
  10. #include "sysdeps.h"
  11.  
  12. #include "config.h"
  13. #include "options.h"
  14. #include "events.h"
  15. #include "memory.h"
  16. #include "custom.h"
  17. #include "newcpu.h"
  18. #include "disk.h"
  19. #include "xwin.h"
  20. #include "autoconf.h"
  21. #include "hardfile.h"
  22.  
  23. static int opencount = 0;
  24. static int uaedevfd;
  25. static int numtracks = 512;
  26.  
  27. static ULONG dosname, uaedevname;
  28.  
  29. static ULONG hardfile_init(void)
  30. {
  31.     ULONG tmp1, tmp2, tmp3,configdev;
  32.     int have36 = 1;
  33.     ULONG retval = regs.d[0];
  34.  
  35.     if (!automount_uaedev)
  36.     return retval;
  37.  
  38.     regs.d[0] = 88; regs.d[1] = 1; /* MEMF_PUBLIC */
  39.     tmp1 = CallLib (regs.a[6], -198); /* AllocMem() */
  40.     if (tmp1 == 0) {
  41.     fprintf(stderr, "Not enough memory for uae.device!\n");
  42.     return 0;
  43.     }
  44.     /* Open expansion.lib */
  45.     regs.d[0] = 36; /* Let's try this... */
  46.     regs.a[1] = explibname;
  47.     regs.a[4] = CallLib (regs.a[6], -552); /* OpenLibrary() */
  48.     if (regs.a[4])
  49.     have36 = 1;
  50.     else {
  51.     regs.d[0] = 0;
  52.     regs.a[1] = explibname;
  53.     regs.a[4] = CallLib (regs.a[6], -552); /* OpenLibrary() */
  54.     }
  55.     put_long (tmp1, dosname);
  56.     put_long (tmp1+4, uaedevname);
  57.     put_long (tmp1+8, 0); /* Unit no. */
  58.     put_long (tmp1+12, 0); /* Device flags */
  59.     put_long (tmp1+16, 16); /* Env. size */
  60.     put_long (tmp1+20, 128); /* 512 bytes/block */
  61.     put_long (tmp1+24, 0); /* unused */
  62.     put_long (tmp1+28, 1); /* heads */
  63.     put_long (tmp1+32, 1); /* unused */
  64.     put_long (tmp1+36, 32); /* secs per track */
  65.     put_long (tmp1+40, 1); /* reserved blocks */
  66.     put_long (tmp1+44, 0); /* unused */
  67.     put_long (tmp1+48, 0); /* interleave */
  68.     put_long (tmp1+52, 0); /* lowCyl */
  69. #ifndef __DOS__
  70.     put_long (tmp1+56, 511); /* upperCyl */
  71. #else
  72.     put_long (tmp1+56, numtracks-1); /* upperCyl */
  73. #endif
  74.     put_long (tmp1+60, 0); /* Number of buffers */
  75.     put_long (tmp1+64, 0); /* Buffer mem type */
  76.     put_long (tmp1+68, 0x7FFFFFFF); /* largest transfer */
  77.     put_long (tmp1+72, ~1); /* addMask (?) */
  78.     put_long (tmp1+76, (ULONG)-1); /* bootPri */
  79.     if (have36)
  80.     put_long (tmp1+80, 0x444f5301); /* DOS\1 */
  81.     else
  82.     put_long (tmp1+80, 0x444f5300); /* DOS\0 */
  83.  
  84.  
  85.     put_long (tmp1+84, 0); /* pad */
  86.     regs.a[0] = tmp1;
  87.     tmp2 = CallLib (regs.a[4], -144); /* MakeDosNode() */
  88.  
  89.     configdev = CallLib(regs.a[4], -48); /* AllocConfigDev() */
  90.  
  91.     /* hier init der Configdev */
  92.  
  93.     regs.a[0] = tmp2;
  94.     regs.d[0] = (ULONG)-1;
  95.     regs.a[1] = configdev;
  96.     regs.d[1] = 0;
  97. #if 0
  98.     CallLib (regs.a[4], -150); /* AddDosNode() */
  99. #endif
  100.  
  101.  
  102. #if 1
  103. #if 1
  104.     if (have36)
  105.     CallLib (regs.a[4], /*-150*/ -36); /* AddDosNode() */
  106.     else {
  107. #endif
  108.         /* We could also try to call AddBootNode() here - but we don't have
  109.      * a ConfigDev. */
  110.     regs.d[0] = 20;
  111.     regs.d[1] = 0;
  112.     tmp3 = CallLib (regs.a[6], -198);
  113.     if (tmp3 == 0) {
  114.         fprintf(stderr, "Not enough memory for uae.device bootnode!\n");
  115.         return 0;
  116.     }
  117.     put_word (tmp3 + 14, 0);
  118.     put_long (tmp3 + 16, tmp2);
  119.     put_word (tmp3 + 8, 0x1005);
  120.     put_long (tmp3 + 10, 0);
  121.     put_long (tmp3 + 0, 0);
  122.     put_long (tmp3 + 4, 0);
  123.     regs.a[0] = regs.a[4] + 74; /* MountList */
  124.     regs.a[1] = tmp3;
  125.     CallLib (regs.a[6], -270); /* Enqueue() */
  126. #if 1
  127.     }
  128. #endif
  129. #endif
  130.  
  131.     regs.a[1] = tmp1;
  132.     regs.d[0] = 88;
  133.     CallLib (regs.a[6], -210); /* FreeMem() */
  134.  
  135.     regs.a[1] = regs.a[4];
  136.     CallLib (regs.a[6], -414); /* CloseLibrary() */
  137.  
  138.     return retval;
  139. }
  140.  
  141. static ULONG hardfile_open(void)
  142. {
  143.     CPTR tmp1 = regs.a[1]; /* IOReq */
  144.  
  145.     /* Check unit number */
  146.     if (regs.d[0] == 0) {
  147.     opencount++;
  148.     put_word (regs.a[6]+32, get_word (regs.a[6]+32) + 1);
  149.     put_long (tmp1+24, 0); /* io_Unit */
  150.     put_byte (tmp1+31, 0); /* io_Error */
  151.     put_byte (tmp1+8, 7); /* ln_type = NT_REPLYMSG */
  152.     return 0;
  153.     }
  154.  
  155.     put_long (tmp1+20, (ULONG)-1);
  156.     put_byte (tmp1+31, (UBYTE)-1);
  157.     return (ULONG)-1;
  158. }
  159.  
  160. static ULONG hardfile_close(void)
  161. {
  162.     opencount--;
  163.     put_word (regs.a[6]+32, get_word (regs.a[6]+32) - 1);
  164.  
  165.     return regs.d[0];
  166. }
  167.  
  168. static ULONG hardfile_expunge(void)
  169. {
  170.     return 0; /* Simply ignore this one... */
  171. }
  172.  
  173. static ULONG hardfile_beginio(void)
  174. {
  175.     ULONG tmp1, tmp2, dataptr, offset;
  176.     ULONG retval = regs.d[0];
  177.  
  178.     tmp1 = regs.a[1];
  179.     put_byte (tmp1+8, 5); /* set ln_type to NT_MESSAGE */
  180.     put_byte (tmp1+31, 0); /* no error yet */
  181.     tmp2 = get_word (tmp1+28); /* io_Command */
  182.     switch (tmp2) {
  183.      case 2: /* Read */
  184.     dataptr = get_long (tmp1 + 40);
  185.     if (dataptr & 1)
  186.         goto bad_command;
  187.     offset = get_long (tmp1 + 44);
  188.     if (offset & 511)
  189.         goto bad_command;
  190.     tmp2 = get_long (tmp1 + 36); /* io_Length */
  191.     if (tmp2 & 511)
  192.         goto bad_command;
  193.     if (tmp2 + offset > (ULONG)numtracks * 32 * 512)
  194.         goto bad_command;
  195.  
  196.     put_long (tmp1 + 32, tmp2); /* set io_Actual */
  197.     lseek (uaedevfd, offset, SEEK_SET);
  198.     while (tmp2) {
  199.         int i;
  200.         char buffer[512];
  201.         read (uaedevfd, buffer, 512);
  202.         for (i = 0; i < 512; i++, dataptr++)
  203.         put_byte(dataptr, buffer[i]);
  204.         tmp2 -= 512;
  205.     }
  206.     break;
  207.  
  208.      case 3: /* Write */
  209.      case 11: /* Format */
  210.     dataptr = get_long (tmp1 + 40);
  211.     if (dataptr & 1)
  212.         goto bad_command;
  213.     offset = get_long (tmp1 + 44);
  214.     if (offset & 511)
  215.         goto bad_command;
  216.     tmp2 = get_long (tmp1 + 36); /* io_Length */
  217.     if (tmp2 & 511)
  218.         goto bad_command;
  219.     if (tmp2 + offset > (ULONG)numtracks * 32 * 512)
  220.         goto bad_command;
  221.  
  222.     put_long (tmp1 + 32, tmp2); /* set io_Actual */
  223.     lseek (uaedevfd, offset, SEEK_SET);
  224.     while (tmp2) {
  225.         char buffer[512];
  226.         int i;
  227.         for (i=0; i < 512; i++, dataptr++)
  228.         buffer[i] = get_byte(dataptr);
  229.         write (uaedevfd, buffer, 512);
  230.         tmp2 -= 512;
  231.     }
  232.     break;
  233.  
  234.     bad_command:
  235.     break;
  236.  
  237.      case 18: /* GetDriveType */
  238.     put_long (tmp1 + 32, 1); /* not exactly a 3.5" drive, but... */
  239.     break;
  240.  
  241.      case 19: /* GetNumTracks */
  242.     put_long (tmp1 + 32, numtracks);
  243.     break;
  244.  
  245.     /* Some commands that just do nothing and return zero */
  246.      case 4: /* Update */
  247.      case 5: /* Clear */
  248.      case 9: /* Motor */
  249.      case 10: /* Seek */
  250.      case 12: /* Remove */
  251.      case 13: /* ChangeNum */
  252.      case 14: /* ChangeStatus */
  253.      case 15: /* ProtStatus */
  254.      case 20: /* AddChangeInt */
  255.      case 21: /* RemChangeInt */
  256.     put_long (tmp1+32, 0); /* io_Actual */
  257.     retval = 0;
  258.     break;
  259.  
  260.      default:
  261.     /* Command not understood. */
  262.     put_byte (tmp1+31, (UBYTE)-3); /* io_Error */
  263.     retval = 0;
  264.     break;
  265.     }
  266.     if ((get_byte (tmp1+30) & 1) == 0) {
  267.     /* Not IOF_QUICK -- need to ReplyMsg */
  268.     regs.a[1] = tmp1;
  269.     CallLib (get_long(4), -378);
  270.     }
  271.     return retval;
  272. }
  273.  
  274. static ULONG hardfile_abortio(void)
  275. {
  276.     return (ULONG)-3;
  277. }
  278.  
  279. void hardfile_install(void)
  280. {
  281.     ULONG devid, functable, datatable, inittable, begin, end;
  282.     ULONG initroutine, openfunc, closefunc, expungefunc;
  283.     ULONG nullfunc, beginiofunc, abortiofunc;
  284.  
  285.     uaedevfd = open ("hardfile", O_RDWR | O_BINARY);
  286.  
  287.     if (uaedevfd < 0)
  288.     return;
  289.  
  290. #ifdef __DOS__
  291.     numtracks = filelength(uaedevfd) / 16384;
  292. #endif
  293.  
  294.     uaedevname = ds("uae.device");
  295.     devid = ds("uae 0.4"); /* ID */
  296.     dosname = ds("UAEHF"); /* This is the DOS name */
  297.  
  298.     begin = here();
  299.     dw(0x4AFC); /* RTC_MATCHWORD */
  300.     dl(begin); /* our start address */
  301.     dl(0); /* Continue scan here */
  302.     dw(0x8101); /* RTF_AUTOINIT|RTF_COLDSTART; Version 1 */
  303.     dw(0x0305); /* NT_DEVICE; pri 5 */
  304.     dl(uaedevname); /* name */
  305.     dl(devid); /* ID */
  306.     dl(here() + 4); /* Init area: directly after this */
  307.     /* Init area starts here */
  308.     dw(0x0000); /* Not really sure what to put here */
  309.     dw(0x0100);
  310.     inittable = here();
  311.     dl(0); dl(0); dl(0); /* skip 3 longs */
  312.  
  313.     /* InitRoutine */
  314.     initroutine = here();
  315.     calltrap(deftrap(hardfile_init)); dw(RTS);
  316.  
  317.     /* Open */
  318.     openfunc = here();
  319.     calltrap(deftrap(hardfile_open)); dw(RTS);
  320.  
  321.     /* Close */
  322.     closefunc = here();
  323.     calltrap(deftrap(hardfile_close)); dw(RTS);
  324.  
  325.     /* Expunge */
  326.     expungefunc = here();
  327.     calltrap(deftrap(hardfile_expunge)); dw(RTS);
  328.  
  329.     /* Null */
  330.     nullfunc = here();
  331.     dw(0x7000); /* return 0; */
  332.     dw(RTS);
  333.  
  334.     /* BeginIO */
  335.     beginiofunc = here();
  336.     calltrap(deftrap(hardfile_beginio)); dw(RTS);
  337.  
  338.     /* AbortIO */
  339.     abortiofunc = here();
  340.     calltrap(deftrap(hardfile_abortio)); dw(RTS);
  341.  
  342.     /* FuncTable */
  343.     functable = here();
  344.     dl(openfunc); /* Open */
  345.     dl(closefunc); /* Close */
  346.     dl(expungefunc); /* Expunge */
  347.     dl(nullfunc); /* Null */
  348.     dl(beginiofunc); /* BeginIO */
  349.     dl(abortiofunc); /* AbortIO */
  350.     dl(0xFFFFFFFF); /* end of table */
  351.  
  352.     /* DataTable */
  353.     datatable = here();
  354.     dw(0xE000); /* INITBYTE */
  355.     dw(0x0008); /* LN_TYPE */
  356.     dw(0x0300); /* NT_DEVICE */
  357.     dw(0xC000); /* INITLONG */
  358.     dw(0x000A); /* LN_NAME */
  359.     dl(uaedevname);
  360.     dw(0xE000); /* INITBYTE */
  361.     dw(0x000E); /* LIB_FLAGS */
  362.     dw(0x0600); /* LIBF_SUMUSED | LIBF_CHANGED */
  363.     dw(0xD000); /* INITWORD */
  364.     dw(0x0014); /* LIB_VERSION */
  365.     dw(0x0004); /* 0.4 */
  366.     dw(0xD000);
  367.     dw(0x0016); /* LIB_REVISION */
  368.     dw(0x0000);
  369.     dw(0xC000);
  370.     dw(0x0018); /* LIB_IDSTRING */
  371.     dl(devid);
  372.     dw(0x0000); /* end of table */
  373.  
  374.     end = here();
  375.  
  376.     org(inittable);
  377.     dl(functable);
  378.     dl(datatable);
  379.     dl(initroutine);
  380.  
  381.     org(begin + 6);
  382.     dl(end);
  383.  
  384.     org(end);
  385. }
  386.